import { message } from 'antd';
import React, { useEffect, useImperativeHandle, useState } from 'react';
import { local } from '../../../helper/storage';
import QueryPanel, { setInputConfig, processSubmitValue } from '../../elastic/QueryPanel';
import TablePanel, { PageInfo, RenderType, renderTypeConfirm } from '../../elastic/TablePanel';
import { GlobalSet } from '../../elastic/TablePanel'
import styles from './index.module.sass';

interface TableParams {
    /**查询参数 */
    queryParams: any

    /**分页信息 */
    pageInfo: PageInfo
}

export interface Global extends GlobalSet {
    /**指定页面的初始展示列数量 */
    defaultLimit?: number

    /**是否紧凑布局 */
    isCompact?: boolean

    /**是否不鉴权，鉴权函数[handleAuthTableButtons]具体实现需要定义在全局对象window上 */
    isNotAuth?: boolean
}

export interface TableData {
    /**表格数据项 */
    data: any[]

    /**表格总数 */
    total?: number
}

interface TableRequest {
    (pageInfo: PageInfo, queryParams?: any): Promise<TableData>;
}

interface Props {
    /**列表标题名称 */
    title?: string

    /**列表的异步请求函数，必须是return new Promise或者async function，并且第一个参数是分页数据，第二个数据是查询数据 */
    request?: TableRequest

    /**表格请求额外的参数 */
    requestParams?: any

    /**列表项配置 */
    columns: any[]

    /**列表头部按钮配置项 */
    buttons?: any[]

    /**列表查询面板配置项 */
    query?: any[][]

    /**查询表单要装填的数据，设置查询表单的默认值 */
    queryData?: any

    /**表格的全局属性设置 */
    global?: Global

    /**表格key值 */
    rowKey?: string

    /**经 Form.useForm() 创建的 form 控制查询实例 */
    queryFormInstance?: any

    /**页面搜索重置时的特殊处理 */
    specialHandleReset?: Function

    /**表格发生改变时的特殊处理 */
    handleChange?: Function
}

const TableInterface = React.forwardRef(({
    columns,
    requestParams,
    title,
    request,
    buttons,
    query,
    queryData,
    rowKey,
    global,
    queryFormInstance,
    specialHandleReset,
    handleChange
}: Props, ref) => {
    console.debug('TableInterface');

    useImperativeHandle(ref, () => ({
        refresh: () => {
            handleRefresh();
        },
        exportParams: () => {
            return {
                ...tableParams,
                ...requestParams
            }
        },
    }));

    const [tableKey] = useState(() => CryptoJS.MD5(JSON.stringify(columns.map(item => item[0]))).toString())

    const [dataSource, setDataSource] = useState<any[]>([]);
    const [total, setTotal] = useState(0);
    const [refreshCount, setRefreshCount] = useState(0);
    const [isLoading, setIsLoading] = useState(false);
    const [clearSelect, setClearSelect] = useState(0);

    const [tableParams, setTableParams] = useState<TableParams>(() => {
        let _pageSize = local(`TableInterfacePageSize${tableKey}`) || global?.defaultLimit || 10;
        return {
            pageInfo: {
                pageIndex: 1,
                pageSize: _pageSize,
            },
            queryParams: queryData
        }
    })

    /**
     * 用于表头操作按钮
     * 鉴权函数[handleAuthTableButtons]具体实现需要定义在全局对象window上
     */
    const [authButtons, setAuthButtons] = useState(() => {
        const handleAuthTableButtons: Function = _.get(window, 'handleAuthTableButtons', false);
        let authButtons = buttons;
        if (!global?.isNotAuth && buttons && handleAuthTableButtons) {
            authButtons = handleAuthTableButtons(buttons);
        }
        return authButtons;
    })

    /**
     * 用于列表项操作按钮
     * 鉴权函数[handleAuthTableButtons]具体实现需要定义在全局对象window上
     */
    const [authColumns, setAuthColumns] = useState(() => {
        const handleAuthTableButtons: Function = _.get(window, 'handleAuthTableButtons', false);
        let authColumns = _.clone(columns);
        const actionIdx = columns.findIndex(item => renderTypeConfirm(item) === RenderType.action);
        if (!global?.isNotAuth && actionIdx !== -1 && handleAuthTableButtons) {
            const authActions = handleAuthTableButtons(columns[actionIdx]);
            if (authActions.length > 0) {
                authColumns[actionIdx] = authActions;
            } else {
                // 没有操作按钮时，取消操作栏
                authColumns = authColumns.filter((item: any, index: any) => index !== actionIdx);
            }
        }
        return authColumns;
    })

    useEffect(() => {
        async function main() {
            try {
                if (request) {
                    setIsLoading(true)
                    let _queryParams = {
                        ...requestParams,
                        ...tableParams.queryParams
                    };

                    query && setInputConfig(query, (queryInputs: any) => {
                        _queryParams = processSubmitValue(queryInputs, _queryParams)
                    })

                    let data = await request({ ...tableParams.pageInfo }, _queryParams);
                    if ((data.data && data.data.length !== 0) || tableParams.pageInfo.pageIndex === 1) {
                        if (typeof (data.total) === 'number' && data.total >= 0) {
                            setTotal(data.total);
                        }
                        if (_.isArray(data.data)) {
                            setDataSource(data.data);
                        } else {
                            console.error('表格数据对象{data}必须是数组，data:', data.data);
                        }
                        setIsLoading(false);
                    } else {
                        setTableParams(val => {
                            val.pageInfo.pageIndex = val.pageInfo.pageIndex - 1
                            return { ...val };
                        });
                    }
                    // 表格数据请求时，自动清除表格中的选中
                    setClearSelect((val) => ++val);
                }
            } catch (error) {
                console.warn('表格数据处理异常', error);
                setIsLoading(false);
                message.error(`表格数据加载异常`);
            }
        }
        main();
    }, [request, tableParams, refreshCount, requestParams, query])

    useEffect(() => {
        const handleAuthTableButtons: Function = _.get(window, 'handleAuthTableButtons', false);
        let authButtons = buttons;
        if (!global?.isNotAuth && buttons && handleAuthTableButtons) {
            authButtons = handleAuthTableButtons(buttons);
        }
        setAuthButtons(authButtons);
    }, [buttons, global])

    useEffect(() => {
        const handleAuthTableButtons: Function = _.get(window, 'handleAuthTableButtons', false);
        let authColumns = _.clone(columns);
        const actionIdx = columns.findIndex(item => renderTypeConfirm(item) === RenderType.action);
        if (!global?.isNotAuth && actionIdx !== -1 && handleAuthTableButtons) {
            const authActions = handleAuthTableButtons(columns[actionIdx]);
            if (authActions.length > 0) {
                authColumns[actionIdx] = authActions;
            } else {
                // 没有操作按钮时，取消操作栏
                authColumns = authColumns.filter((item: any, index: any) => index !== actionIdx);
            }
        }
        setAuthColumns(authColumns);
    }, [columns, global])

    function handleQuery(params: any) {
        setTableParams(val => {
            val.pageInfo.pageIndex = 1;
            val.queryParams = params;
            return { ...val };
        });
    }

    function handleReset() {
        setTableParams(val => {
            val.pageInfo.pageIndex = 1;
            val.queryParams = queryData;
            specialHandleReset && specialHandleReset(val);
            return { ...val };
        });
    }

    function handlePagination(_pageIndex: number, _pageSize?: number) {
        setTableParams(val => {
            val.pageInfo.pageIndex = _pageIndex;
            if (_pageSize) {
                val.pageInfo.pageSize = _pageSize;
                local(`TableInterfacePageSize${tableKey}`, _pageSize);
            }
            return { ...val };
        });
    }

    function handleRefresh() {
        setRefreshCount(val => ++val);
    }



    return (
        <article className={global?.isCompact ? styles.wrapperCompact : styles.wrapper}>

            {(title || query) &&
                <header className={styles.header}>
                    {title &&
                        <div className={styles.title}>{title}</div>
                    }
                    {query &&
                        <QueryPanel
                            inputs={query}
                            queryData={queryData}
                            onSubmit={handleQuery}
                            onReset={handleReset}
                            formInstance={queryFormInstance}
                        />
                    }
                </header>
            }

            <section className={`${styles.table} table-interface`}>
                <TablePanel
                    rowKey={rowKey}
                    buttons={authButtons}
                    queryParams={tableParams.queryParams}
                    columns={authColumns}
                    dataSource={dataSource}
                    onPagination={handlePagination}
                    onRefresh={handleRefresh}
                    pageIndex={tableParams.pageInfo.pageIndex}
                    pageSize={tableParams.pageInfo.pageSize}
                    total={total}
                    isLoading={isLoading}
                    handleChange={handleChange}
                    global={{
                        ...global,
                        clearSelect
                    }}
                ></TablePanel>
            </section>

        </article>
    )
})

export default TableInterface;